package com.bsoft.exchange.service;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.bsoft.exchange.dao.his.*;
import com.bsoft.exchange.domain.*;
import com.bsoft.exchange.param.FeeSettlement;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.bsoft.exchange.dao.portal.HospitalInformationMapper;
import com.bsoft.exchange.pojo.AppointmentPayPojo;
import com.bsoft.exchange.pojo.ListTakeNumberDataPojo;
import com.bsoft.exchange.pojo.ListTakeNumberPojo;
import com.bsoft.exchange.pojo.PaymentBudgetPojo;
import com.bsoft.exchange.pojo.TakeNumberPojo;
import com.bsoft.exchange.util.BaseResponse;
import com.bsoft.exchange.util.Constant;
import com.bsoft.exchange.util.DateUtil;

@Service
public class TakenumberService {

	@Autowired
	RegisterMapper registerMapper;
	
	@Autowired
	HospitalInformationMapper hospitalInformationMapper;
	
	@Autowired
	TakenumberMapper takenumberMapper;
	
	@Autowired
	SystemConfigMapper systemConfigMapper;
	
	@Autowired
	AppointmentInfomationMapper appointmentInfomationMapper;
	
	@Autowired
	SourceNumberMapper sourceNumberMapper;
	
	@Autowired
	DepartmentScheduleMapper departmentScheduleMapper;

	@Autowired
	DoctorScheduleMapper doctorScheduleMapper;
	
	@Autowired
	PublicService publicService;
	
	@Autowired
	CreateOrderNoService createOrderNoService;
	
	@Autowired
	QueueCallService queueCallService;
	
	@Autowired
	RegisterService registerService;
	
	@Autowired
	PatientMapper patientMapper;

	@Autowired
	YBService ybService;

	@Autowired
	AppointmentMapper appointmentMapper;


	private static final Logger logger = LoggerFactory.getLogger(TakenumberService.class);
	
	/**
	 * 执行挂号支付预结算/签到取号预结算时调用
	 * @param paymentBudgetPojo
	 * @return
	 */

	public BaseResponse<Map<String,Object>> paymentBudget(PaymentBudgetPojo paymentBudgetPojo){
		logger.info(" ========= 挂号登记预结算 ：{} ==========",paymentBudgetPojo);
		Map<String, Object> data = new HashMap<>();
		
		BaseResponse<Map<String,Object>>baseResponse=new BaseResponse<>();
		
		String  hospitalCode = paymentBudgetPojo.getOrganizationId();//医院ID
		String hisOrderNumber = paymentBudgetPojo.getOrderId();//医院挂号预约流水号
		
		Long yyxh;
		Long jgid;
		if(hisOrderNumber == null || "".equals(hisOrderNumber)){
			baseResponse.setCode(Constant.errorTag);
            baseResponse.setMessage("预约序号不能为空!");
            
            return baseResponse;
		}
		jgid = 1L;
		yyxh = Long.parseLong(hisOrderNumber);
		
		//判断是否已经收过费

		//获取挂号预约信息
		AppointmentInfomationDomain appointmentInfomation = appointmentInfomationMapper.getAppointmentInfoById(yyxh);
		
		if(appointmentInfomation ==null){
			baseResponse.setCode(Constant.breakTag);
            baseResponse.setMessage("根据预约序号"+hisOrderNumber+"获取预约信息失败!");
            
            return baseResponse;
		}
		
		//brid判断
		if(appointmentInfomation.getBrid() ==null || appointmentInfomation.getBrid() <= 0){
			if(appointmentInfomation.getSfzh() == null || "".equals(appointmentInfomation.getSfzh())){
				baseResponse.setCode(Constant.breakTag);
	            baseResponse.setMessage("预约序号"+hisOrderNumber+"的预约信息病人id和身份证号同时为空!");
	            
	            return baseResponse;
			}else{
				
				//根据身份证号查询brid
				Map<String, Object> args = new HashMap<String, Object>();
				args.put("sfzh", appointmentInfomation.getSfzh());
				List<PatientDomain> patientList = patientMapper.getPhoneAndCards(args);
				
				if(patientList == null || patientList.size()==0){
					baseResponse.setCode(Constant.breakTag);
		            baseResponse.setMessage("该预约信息的身份证号未建档，请先建档!");
		            
		            return baseResponse;
				}
				
				if(patientList !=null && patientList.size() > 1){
					baseResponse.setCode(Constant.breakTag);
		            baseResponse.setMessage("该预约信息的身份证号有多条档案信息，请先去档案绑定!");
		            
		            return baseResponse;
				}
				
				//唯一档案时候 更新预约信息的brid
				if(patientList !=null && patientList.size() == 1){
					appointmentInfomation.setBrid(patientList.get(0).getBrid());
					appointmentInfomationMapper.updateAppInfoBrid(appointmentInfomation);
				}
				
			}
		}
		
		if(appointmentInfomation.getYyzt() != null && appointmentInfomation.getYyzt() > 0){
			baseResponse.setCode(Constant.breakTag);
            baseResponse.setMessage("该预约序号"+hisOrderNumber+"已经挂号!");
            
            return baseResponse;
		}
		
		Long brid  = appointmentInfomation.getBrid();
		
		//根据预约序号 获取号源信息
		SourceNumberDomain sourceNumber = sourceNumberMapper.getSourceNumberByYyxh(yyxh);
		if(sourceNumber == null ){
       	 	baseResponse.setCode(Constant.breakTag);
            baseResponse.setMessage("根据预约序号"+hisOrderNumber+"获取号源信息失败!");

            return baseResponse;
        }
		//根据号源信息，获取排班信息
		Integer ghrq;
		String ysdm;
		Map<String, Object> param = new HashMap<String, Object>();

		Map<String, Object> yspbParam = new HashMap<String, Object>();


		ghrq = DateUtil.getDayofweek(sourceNumber.getGzrq());
		param.put("jgid", jgid);
		param.put("ghrq", ghrq);
		param.put("zblb", sourceNumber.getZblb());
		param.put("ghks", sourceNumber.getGhks());

		ysdm = sourceNumber.getYsdm();
		
		Integer jzxh = 0 ;
		Integer ghlb;
		boolean yspb = false;
		Integer ysbz = 0 ;
		Double ghje;
		Double zlje;
		Double zjfy;
		Double blje =0.00;
		Double jzje =0.00;
		Double qtys =0.00;
		Double payAmount = 0.00;
		String settlementDetails = "";
		
		//获取节假日挂号费浮动参数
		String jjrfd = systemConfigMapper.getValueByConfigName(jgid, "MS_JJR_GHFFD");
		if(jjrfd == null || "".equals(jjrfd)){
			jjrfd = "0";
		}
		
		if("1".equals(jjrfd)){
			String dmmc="";
			Integer jjr;
			if(ghrq != 1 && ghrq !=7){
				dmmc = DateUtil.dateFormatDay(sourceNumber.getGzrq()).replace("-", ".");
				jjr = takenumberMapper.checkJJR(dmmc);
				if( jjr == null || jjr <= 0){
					jjrfd = "0";
				}
			}
			
		}
		
		
//				id_bldj = Double(gf_his_share_getpara(go_jgxx.il_jgid,"BLDJ","0.50","病历费单价"))
//				id_jzdj = Double(gf_his_share_getpara(go_jgxx.il_jgid,"JZDJ","0.50","就诊卡费单价"))
				
		//判断是否停挂
		//判断是否超过限

		//科室排班
		DepartmentScheduleDomain departmentSchedule = new DepartmentScheduleDomain();
				
		//医生排班
		DoctorScheduleDomain doctorSchedule = new DoctorScheduleDomain();

		//医生代码为空的为科室排班
		if(ysdm == null || "".equals(ysdm)){
			
			departmentSchedule = departmentScheduleMapper.getDepartmentSchedule(param);
			
			if(departmentSchedule == null ){
	       	 	baseResponse.setCode(Constant.breakTag);
	            baseResponse.setMessage("查询对应的科室排班信息失败!");
	            
	            return baseResponse;
			}
			
			if(departmentSchedule.getTgbz() == 1){
				baseResponse.setCode(Constant.breakTag);
	            baseResponse.setMessage("该科室已经停挂，请选择其他科室!");
	            
	            return baseResponse;
			}
			
			if(departmentSchedule.getYyxe() != 0 && departmentSchedule.getYyrs() >= departmentSchedule.getYyxe()){
				baseResponse.setCode(Constant.breakTag);
	            baseResponse.setMessage("已超过科室预挂限额!");
	            
	            return baseResponse;
			}
			
			jzxh = departmentSchedule.getJzxh() + 1 ;
			ghlb = departmentSchedule.getGhlb();
			
			ghje = departmentSchedule.getGhf();
			if("1".equals(jjrfd)){
				ghje = departmentSchedule.getJjrghf();
			}
			payAmount += ghje;

			zlje = departmentSchedule.getZlf();
			payAmount += zlje;
	
			zjfy = (double) 0;
			settlementDetails = "总费用："+payAmount+"，其中挂号费："+ghje+"，诊疗费："+zlje;
		}else{
			yspb = true;
			ysbz = 1;
			Date gzrq_begin = DateUtil.getDateByZeroTime(sourceNumber.getGzrq(),0);
			Date gzrq_end = DateUtil.getDateByZeroTime(sourceNumber.getGzrq(),1);

			yspbParam.put("jgid", 1);
			yspbParam.put("gzrq_begin", gzrq_begin);
			yspbParam.put("gzrq_end", gzrq_end);
			yspbParam.put("zblb", sourceNumber.getZblb());
			yspbParam.put("ksdm", sourceNumber.getGhks());
			yspbParam.put("ysdm", ysdm);

			logger.info("医生排班查询入参   ====>{}",yspbParam);
			doctorSchedule = doctorScheduleMapper.getDoctorSchedule(yspbParam);
			logger.info("医生排班查询出参   ====>{}",doctorSchedule);

			
			if(doctorSchedule == null ){
	       	 	baseResponse.setCode(Constant.breakTag);
	            baseResponse.setMessage("查询对应的医生排班信息失败!");
	            
	            return baseResponse;
			}	

			if(doctorSchedule.getTgbz() == 1){
				baseResponse.setCode(Constant.breakTag);
	            baseResponse.setMessage("该医生已经停挂，请选择其他科室或医生!");
	            
	            return baseResponse;
			}
			
			if(doctorSchedule.getYyxe() != 0 && doctorSchedule.getYyrs() >= doctorSchedule.getYyxe()){
				baseResponse.setCode(Constant.breakTag);
	            baseResponse.setMessage("已超过医生预挂限额!");
	            
	            return baseResponse;
			}
			
			jzxh = doctorSchedule.getJzxh() + 1 ;
			ghlb = doctorSchedule.getGhlb();
			ghje = doctorSchedule.getGhf();
			if("1".equals(jjrfd)){
				ghje = doctorSchedule.getJjrghf();
			}
			payAmount += ghje;
			
			zlje = doctorSchedule.getZlf();
			payAmount += zlje;
			settlementDetails = "总费用："+payAmount+"，其中挂号费："+ghje+"，诊疗费："+zlje;
			
			if(doctorSchedule.getZjmz() !=null && doctorSchedule.getZjmz() == 1){
				zjfy = doctorSchedule.getZjfy();
				payAmount += zjfy;
				settlementDetails = "总费用："+payAmount+"，其中挂号费："+ghje+"，诊疗费："+zlje+"，专家费："+zjfy;
			}
			
		}
		String outOrderNumber ="";
		try {
			//获取商户订单号  	业务类别：1，挂号，2 诊间支付，3预缴金充值，4住院结算
			int zffs = 0;
			BaseResponse<String> orderResponse = createOrderNoService.createShddh(jgid.intValue(), 1, zffs, payAmount, brid.intValue());

			if(orderResponse.getCode() != Constant.successTag){
				baseResponse.setCode(orderResponse.getCode());
	            baseResponse.setMessage(orderResponse.getMessage());

	            return baseResponse;
			}

			outOrderNumber = orderResponse.getData();
			logger.info("======= 商户订单号: {} ========",outOrderNumber);

		} catch (Exception e) {
			e.printStackTrace();
			baseResponse.setCode(Constant.errorTag);
            baseResponse.setMessage("获取商户订单号失败!");

            return baseResponse;
		}

		baseResponse.setCode(Constant.successTag);
		
		data.put("payAmount", payAmount);  
		data.put("settlementDetails", settlementDetails);
		data.put("totalFee", payAmount);
		data.put("paymentBudgetNumber", outOrderNumber);
		
		baseResponse.setData(data);		
		return baseResponse;
	}
	
	/**
	 * 获取签到取号列表。
	 * @return
	 */
	public BaseResponse<List<ListTakeNumber>> listTakeNumber(ListTakeNumberPojo listTakeNumberPojo){
		List<ListTakeNumber> list = new ArrayList<>();
		BaseResponse<List<ListTakeNumber>> entry = new BaseResponse<>();
		List<String> brdaList = new ArrayList<>();
		try {
			//获取病人档案
			if (!listTakeNumberPojo.getQueryType().equals(1)){
	            brdaList= publicService.getBRIDist(listTakeNumberPojo.getOrganizationId(),listTakeNumberPojo.getQueryType(),
						listTakeNumberPojo.getPatientIdentityCardList(),listTakeNumberPojo.getPatientMedicalCardNumberList());
	            
	            if (brdaList==null || (brdaList.size() > 0 && "".equals(brdaList.get(0))) || brdaList.size() == 0){
					entry.setCode(Constant.errorTag);
					entry.setMessage("病人查询失败");
		            return entry;
		        }else {//遍历病人档案、插入自己的pojo对象中
//		        	List<ListTakeNumberDataPojo> takeNumberData  = new ArrayList<>();
		        	List<String> takeNumberData  = new ArrayList<>();
		        	for(int i =0 ;i<brdaList.size();i++) {
//		        		ListTakeNumberDataPojo ListTakeNumberDataPojo = new ListTakeNumberDataPojo();
//		        		ListTakeNumberDataPojo.setPatientCode(String.valueOf(brdaList.get(i)));
//		        		takeNumberData.add(ListTakeNumberDataPojo);
		        		takeNumberData.add(String.valueOf(brdaList.get(i)));
					}
		        	listTakeNumberPojo.setPatientIdList(takeNumberData);
		        }
			}
			if (listTakeNumberPojo.getOrganizationId() == null || "".equals(listTakeNumberPojo.getOrganizationId())) {
				entry.setCode(Constant.errorTag);
				entry.setMessage("医院代码不能为空!");
				return entry;
			}
			list = takenumberMapper.listTakeNumber(listTakeNumberPojo);
			entry.setCode(Constant.successTag);
			if(list.size()>0) {
				entry.setMessage("处理成功");
				entry.setData(list);
			}else {
				entry.setMessage("未查询到数据！");
				entry.setData(null);
			}
		} catch (Exception e) {
			e.printStackTrace();
			entry.setCode(Constant.errorTag);
			entry.setMessage("处理失败");
		}
		
		return entry;
	}
	
	/**
	 * 执行获取挂号单时调用。如果his支持线上取号，未取号自动取号，如已取号则查询返回
	 * @param hospitalCode
	 * @param hisOrderNumber
	 * @return
	 */
	public RegisterDomain getRegistrationForm(String hospitalCode, String hisOrderNumber) {
		
		
		return registerService.getRegistrationForm(hospitalCode, hisOrderNumber);
		
//		Long jgid;
//		Long sbxh;
//		jgid = Long.parseLong(hospitalCode);
//		sbxh = Long.parseLong(hisOrderNumber);
//		Double regFee;
//		Integer ghlb;
//		RegisterDomain register = registerMapper.getRegisterById(jgid, sbxh);
//		if (register != null) {
//			HospitalInformation hospital = hospitalInformationMapper.getHospitalById(register.getJgid());
//			if (hospital != null) {
//				register.setJgmc(hospital.getHospitalName());
//			}
//			ghlb = register.getGhlb();
//			regFee = register.getRegFee();
//
//			// 3 专家
//			if (ghlb!= null && ghlb == 3) {
//				regFee += register.getZjfy();
//			}
//			register.setRegFee(regFee);
//
//		}
//		return register;
	}
	
	/**
	 * 签到取号。
	 * @return
	 * @throws SQLException 
	 */
	@Transactional(value="hisTransactionManager",rollbackFor = Exception.class)
	public BaseResponse<TakeNumberDomain> takeNumber(TakeNumberPojo takeNumberPojo) throws SQLException{
		List<ListTakeNumber> list = new ArrayList<>();
		BaseResponse<TakeNumberDomain> entry = new BaseResponse<>();
		int jgid = Integer.valueOf(takeNumberPojo.getOrganizationId());
		int yyxh = Integer.valueOf(takeNumberPojo.getOrderId());
		Integer ghxh = takenumberMapper.getGhxh(yyxh, jgid);
		
		if(ghxh == null){
			entry.setCode(Constant.errorTag);
			entry.setMessage("未找到预约记录");
			return entry;
		}
		
		if(ghxh==0){
			entry.setCode(Constant.errorTag);
			entry.setMessage("未支付挂号，不能取号");
			return entry;
		}
		TakeNumberDomain takeNumberDomain = takenumberMapper.getYygh(yyxh, jgid);
		
		queueCallService.createPdjh(ghxh, jgid);
		
		entry.setCode(Constant.successTag);
		entry.setData(takeNumberDomain);
		entry.setMessage("签到取号成功");
		return entry;
		
		
		
		
	}
	
	
	/**
	 * 执行支付确认时调用。
	 * @param appointmentPayPojo
	 * @return
	 */
	public Map<String,Object> paymentConfirm(AppointmentPayPojo appointmentPayPojo){
		Map<String, Object> data = new HashMap<>();
				
		return data;
	}
}
